using UnityEngine;
using UnityEngine.UI;

/// <summary>
/// GameEvent系统演示类
/// 展示事件系统的注册、触发、移除等功能
/// </summary>
public class EventExamples : MonoBehaviour
{
    //定义按钮
    public Button Btn1, Btn2, Btn3, Btn4;

    // 事件系统实例
    private GameEvent gameEventSystem;

    // 定义一些事件类型常量
    private const string PLAYER_JUMP = "PlayerJump";
    private const string PLAYER_HIT = "PlayerHit";
    private const string GAME_START = "GameStart";
    private const string GAME_OVER = "GameOver";
    private const string SCORE_CHANGE = "ScoreChange";

    void Start()
    {
        // 初始化事件系统
        gameEventSystem = new GameEvent();

        // 测试按钮点击注册和同步触发事件
        Btn1.onClick.AddListener(() =>
        {
            TestBasicEvents();
        });
        //演示一次性事件功能
        Btn2.onClick.AddListener(() =>
        {
            TestOneTimeEvents();
        });
        //演示异步事件功能
        Btn3.onClick.AddListener(() =>
        {
            TestAsyncEvents();
        });
        //演示事件移除功能
        Btn4.onClick.AddListener(() =>
        {
            TestRemoveEvents();
        });
    }

    void Update()
    {
        // 每帧更新事件系统，处理异步事件队列
        gameEventSystem.UpdateEvent();

        // 测试按键触发事件
        if (Input.GetKeyDown(KeyCode.Space))
        {
            // 触发玩家跳跃事件
            gameEventSystem.DispatchEvent(PLAYER_JUMP, 5.0f); // 传递跳跃高度参数
        }

        if (Input.GetKeyDown(KeyCode.H))
        {
            // 触发玩家受伤事件
            gameEventSystem.DispatchEvent(PLAYER_HIT, 10, "敌人攻击"); // 传递伤害值和伤害来源
        }
    }

    /// <summary>
    /// 演示基本事件功能 - 注册和同步触发
    /// </summary>
    private void TestBasicEvents()
    {
        Debug.Log("===== 开始基本事件测试 =====");

        // 注册玩家跳跃事件监听
        gameEventSystem.AddEvent(PLAYER_JUMP, OnPlayerJump);

        // 注册玩家受伤事件监听，使用匿名方法
        gameEventSystem.AddEvent(PLAYER_HIT, (args) => {
            int damage = (int)args[0];
            string source = (string)args[1];
            Debug.Log($"玩家受到 {damage} 点伤害，伤害来源: {source}");
        });

        // 同步触发跳跃事件
        gameEventSystem.DispatchEvent(PLAYER_JUMP, 3.0f);

        // 同步触发受伤事件
        gameEventSystem.DispatchEvent(PLAYER_HIT, 5, "陷阱");

        Debug.Log("===== 基本事件测试完成 =====");
    }

    /// <summary>
    /// 演示一次性事件功能
    /// </summary>
    private void TestOneTimeEvents()
    {
        Debug.Log("===== 开始一次性事件测试 =====");

        // 注册一个一次性游戏开始事件
        gameEventSystem.AddEvent(GAME_START, OnGameStart, true);

        // 第一次触发会执行
        gameEventSystem.DispatchEvent(GAME_START);

        // 第二次触发不会执行，因为已经自动移除了
        gameEventSystem.DispatchEvent(GAME_START);

        Debug.Log("===== 一次性事件测试完成 =====");
    }

    /// <summary>
    /// 演示异步事件功能
    /// </summary>
    private void TestAsyncEvents()
    {
        Debug.Log("===== 开始异步事件测试 =====");

        // 注册分数改变事件
        gameEventSystem.AddEvent(SCORE_CHANGE, OnScoreChange);

        // 异步触发分数改变事件
        gameEventSystem.DispatchAsyncEvent(SCORE_CHANGE, 100);

        Debug.Log("这条消息会在异步事件处理前显示，因为异步事件会在Update中处理");

        Debug.Log("===== 异步事件测试完成 =====");
    }

    /// <summary>
    /// 演示事件移除功能
    /// </summary>
    private void TestRemoveEvents()
    {
        Debug.Log("===== 开始事件移除测试 =====");

        // 注册游戏结束事件
        GameEventHandler gameOverHandler = OnGameOver;
        gameEventSystem.AddEvent(GAME_OVER, gameOverHandler);

        // 触发事件 - 应该能正常执行
        gameEventSystem.DispatchEvent(GAME_OVER, "测试原因");

        // 移除特定处理函数
        gameEventSystem.RemoveEvent(GAME_OVER, gameOverHandler);

        // 再次触发 - 不会有任何输出
        gameEventSystem.DispatchEvent(GAME_OVER, "测试原因2");

        // 测试移除所有事件
        gameEventSystem.AddEvent("TempEvent1", (args) => Debug.Log("临时事件1被执行"));
        gameEventSystem.AddEvent("TempEvent2", (args) => Debug.Log("临时事件2被执行"));

        // 移除所有事件
        gameEventSystem.RemoveEvent();

        // 检查事件是否存在
        Debug.Log($"临时事件1是否存在: {gameEventSystem.HasEvent("TempEvent1")} (应为False)");
        Debug.Log($"临时事件2是否存在: {gameEventSystem.HasEvent("TempEvent2")} (应为False)");

        Debug.Log("===== 事件移除测试完成 =====");
    }

    // ===== 事件处理函数 =====

    /// <summary>
    /// 玩家跳跃事件处理函数
    /// </summary>
    /// <param name="args">事件参数 - 第一个参数是跳跃高度(float)</param>
    private void OnPlayerJump(params object[] args)
    {
        float jumpHeight = (float)args[0];
        Debug.Log($"玩家跳跃! 高度: {jumpHeight}米");
    }
    /// <summary>
    /// 游戏开始事件处理函数
    /// </summary>
    private void OnGameStart(params object[] args)
    {
        Debug.Log("游戏开始事件被触发! (这个事件只会执行一次)");
    }
    /// <summary>
    /// 分数改变事件处理函数
    /// </summary>
    /// <param name="args">事件参数 - 第一个参数是新分数(int)</param>
    private void OnScoreChange(params object[] args)
    {
        int newScore = (int)args[0];
        Debug.Log($"分数改变: 新分数 = {newScore} (这是一个异步事件)");
    }
    /// <summary>
    /// 游戏结束事件处理函数
    /// </summary>
    /// <param name="args">事件参数 - 第一个参数是结束原因(string)</param>
    private void OnGameOver(params object[] args)
    {
        string reason = (string)args[0];
        Debug.Log($"游戏结束! 原因: {reason}");
    }

    void OnDestroy()
    {
        // 清理事件系统
        if (gameEventSystem != null)
        {
            gameEventSystem.Dispose();
        }
    }
}